import LogFactory from "log/LogFactory";
const DB_NAME: "lavender" = "lavender" ;
const DB_KEY_PATH: string = "username" ;
const TABLE_SYSTEM = "system_config" ;
const TABLE_DRP = "drp_config" ;
const TABLE_LOGIN = "login_info" ;
type TableNameType = "system_config" | "drp_config" | "login_info";
const DB_VERSION: number = 1 ;
const log = LogFactory.getLog("IndexedDBStorage") ;
export default class IndexedDBStorage<T> {
    private dataBase: IDBDatabase | null = null ;
    private tableName: string ;
    private databasePromise ;
    constructor(tableName: TableNameType) {
        this.tableName = tableName ;
        this.databasePromise = this.initDataBase() ;
    }

    public dbIsOpen(): boolean {
        return this.dataBase !== null ;
    }

    private async saveHandle(data: T): Promise<boolean> {
        log.debug("保存数据",data) ;
        let db = await this.databasePromise ;
        let ob = db.transaction(this.tableName,"readwrite").objectStore(this.tableName) ;
        let request = ob.put(data);
        return new Promise((resolve, reject) => {
            request.onsuccess = (event: any) => {
                log.debug("保存数据成功",event) ;
                resolve(true) ;
            } ;
            request.onerror = (event: Event) => {
                log.error("保存数据失败",event) ;
                reject(event) ;
            } ;
        }) ;
    }
    private async findHandle(userKey: string): Promise<T> {
        log.debug("查找数据",userKey) ;
        let db = await this.databasePromise ;
        let store = db.transaction(this.tableName,"readonly").objectStore(this.tableName) ;
        return new Promise((resolve, reject) => {
           let request = store.get(userKey) ;
              request.onsuccess = (event: any) => {
               log.debug("查找数据成功",event.target.result) ;
               resolve(event.target.result) ;
           } ;
              request.onerror = (event: Event) => {
                log.error("查找数据失败",event) ;
                reject(event) ;
              } ;
        });
    }
    public async findData(userKey: string): Promise<T> {
       return await this.findHandle(userKey) ;
    }

    /**
     * 保存数据到数据库
     */
    public async saveData(data: T) {
         await this.saveHandle(data) ;
    }

    private indexedDBUpgradeNeeded(event: any){
        log.info("数据库更新",this.tableName,event) ;
        let db: IDBDatabase = event.target.result ;

        db.createObjectStore(TABLE_DRP,{keyPath: DB_KEY_PATH}) ;


        // 创建一个对象存储来存储系统配置的相关信息，我们将“config-key”作为键路径
        // 因为 config-key 可以保证是不重复的——或至少在启动项目的会议上我们是这样被告知的。
        // const objectStore = db.createObjectStore(this.tableName,{keyPath: "_key"}) ;
        // // 创建一个索引以通过用户名和用户id来搜索用户配置,用户名可以重复，但是用户id不会重复，所以我们不能使用 unique 索引。
        // objectStore.createIndex("username","username",{unique: false}) ;
        // objectStore.createIndex("userId","userId",{unique: true}) ;
        // log.debug("创建对象存储的表",objectStore) ;
        // 使用事务的 oncomplete 事件确保在插入数据前对象存储已经创建完毕。
        // objectStore.transaction.oncomplete = (event: Event) => {
        //     // 将数据保存到新创建的对象存储
        //     const customerObjectStore = db.transaction(this.tableName,"readwrite").objectStore(this.tableName) ;
        //     customerObjectStore.add({ssn: "444-44-4444",name: "Bill",age: 35,email: "909425@qq.com"}) ;
        //     customerObjectStore.add({ssn: "555-44-4444",name: "job",age: 21,email: "541952@qq.com"}) ;
        // } ;
    }

    private async initDataBase(): Promise<IDBDatabase> {
       return new Promise((resolve, reject) => {
           let request = indexedDB.open(DB_NAME,DB_VERSION) ;
           request.onsuccess = (event: any) => {
               let db: IDBDatabase = event.target.result ;
               log.debug("数据库打开成功",db) ;
               this.dataBase = db ;
               resolve(db) ;
           } ;
           request.onerror = (event: Event) => {
               log.error("数据库打开失败",event) ;
               reject(event) ;
           } ;
           request.onupgradeneeded = this.indexedDBUpgradeNeeded.bind(this) ;
        } ) ;
    }

    public closeDB() {
        log.debug("关闭数据库连接") ;
        if (this.dataBase !== null){
            this.dataBase.close() ;
        }else {
            this.databasePromise.then(db => db.close()) ;
        }
    }
}